/**
 * Copyright (c) 2006 Amgad S Youssef
 * All Rights Reserved.
 * Licensed under the Eclipse Public License - v 1.0
 * For more information see http://www.eclipse.org/legal/epl-v10.html
 */
package org.eclipsejcde.wizards.jcapplet.pages;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.ui.wizards.NewClassWizardPage;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipsejcde.core.JCDECore;
import org.eclipsejcde.core.defaults.Defaults;

/**
 * @author Amgad S Youssef
 *
 */
public class NewJCAppletWizardPage extends NewClassWizardPage {
	protected String appletAID = Defaults.APPLET_AID;

	protected IStatus appletAIDStatus;

	@Override
	public void init(IStructuredSelection selection) {
		super.init(selection);
		setSuperClass("javacard.framework.Applet", true);
		setMethodStubSelection(false, false, true, false);
	}

	public NewJCAppletWizardPage() {
		setTitle("Java Card Applet");
		setDescription("Create a new Java Card Applet class.");
	}

	@Override
	public void createControl(Composite parent) {
		initializeDialogUnits(parent);

		Composite composite = new Composite(parent, SWT.NONE);
		composite.setFont(parent.getFont());

		int nColumns = 4;

		GridLayout layout = new GridLayout();
		layout.numColumns = nColumns;
		composite.setLayout(layout);

		// pick & choose the wanted UI components

		createContainerControls(composite, nColumns);
		createPackageControls(composite, nColumns);
		createEnclosingTypeControls(composite, nColumns);

		createSeparator(composite, nColumns);

		// Applet AID controls
		GridData span3 = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1);
		Label appletAIDLabel = new Label(composite, SWT.LEFT);
		appletAIDLabel.setText("Applet AID");

		Text appletAIDText = new Text(composite, SWT.BORDER | SWT.SINGLE);
		appletAIDText.setLayoutData(span3);
		appletAIDText.setText(appletAID);
		appletAIDText.addModifyListener(new ModifyListener() {
			@Override
			public void modifyText(ModifyEvent e) {
				Text text = (Text) e.getSource();
				appletAID = text.getText();
				appletAIDStatus = JCDECore.validateAID(appletAID);
				doStatusUpdate();
			}
		});

		createTypeNameControls(composite, nColumns);
		createModifierControls(composite, nColumns);

		createSuperClassControls(composite, nColumns);
		createSuperInterfacesControls(composite, nColumns);

		createCommentControls(composite, nColumns);
		enableCommentControl(true);

		setControl(composite);

		Dialog.applyDialogFont(composite);
	}

	@Override
	public void createType(IProgressMonitor monitor) throws CoreException, InterruptedException {
		super.createType(monitor);
		IType createdType = getCreatedType();
		createdType.getCompilationUnit().createImport("javacard.framework.ISOException", null, monitor);

		StringBuffer content = null;
		// create install method
		IMethod installMethod = createdType.getMethod("install", new String[] { "byte[]", "short", "byte" });
		if (installMethod != null && installMethod.exists()) {
			installMethod.delete(true, monitor);
		}
		content = new StringBuffer();
		content.append("public static void install(byte bArray[], short bOffset, byte bLength) throws ISOException {\n");
		content.append("\tnew " + createdType.getElementName() + "().register();\n");
		content.append("}");
		IMethod[] methods = createdType.getMethods();
		IJavaElement sibling = null;
		if (methods.length > 0) {
			sibling = methods[0];
		}
		IStatus status = JCDECore.formatMethodCode(content.toString(), createdType.getJavaProject());
		if (status.getSeverity() == IStatus.OK) {
			createdType.createMethod(status.getMessage(), sibling, true, monitor);
		} else {
			createdType.createMethod(content.toString(), sibling, true, monitor);
		}

		// create constructor
		IMethod constructor = createdType.getMethod(createdType.getElementName(), new String[] {});
		if (constructor != null && constructor.exists()) {
			constructor.delete(true, monitor);
		}
		content = new StringBuffer();
		content.append("private " + createdType.getElementName() + "() {\n");
		content.append("}");
		methods = createdType.getMethods();
		sibling = null;
		if (methods.length > 0) {
			sibling = methods[0];
		}
		status = JCDECore.formatMethodCode(content.toString(), createdType.getJavaProject());
		if (status.getSeverity() == IStatus.OK) {
			createdType.createMethod(status.getMessage(), sibling, true, monitor);
		} else {
			createdType.createMethod(content.toString(), sibling, true, monitor);
		}

		// set applet AID
		JCDECore.setAppletAID(createdType.getCompilationUnit(), this.appletAID);
	}

	@Override
	protected IStatus packageChanged() {
		IStatus status = JavaConventions.validatePackageName(getPackageText());
		if (status.getSeverity() != IStatus.OK) {
			return status;
		}
		return super.packageChanged();
	}

	private void doStatusUpdate() {
		IStatus[] status = new IStatus[] { fContainerStatus, isEnclosingTypeSelected() ? fEnclosingTypeStatus : fPackageStatus, appletAIDStatus, fTypeNameStatus, fModifierStatus, fSuperClassStatus,
				fSuperInterfacesStatus };
		updateStatus(status);
	}

}
